package Class_Test;

import java.io.File;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

public class Test
{
	public static void main(String[] args)
	{
		try
		{
			//Constructor_Test();
			//Method_Test();
			Field_Test();
		} catch (InstantiationException e)
		{
			throw new RuntimeException(e);
		} catch (IllegalAccessException e)
		{
			throw new RuntimeException(e);
		} catch (NoSuchMethodException e)
		{
			throw new RuntimeException(e);
		} catch (InvocationTargetException e)
		{
			throw new RuntimeException(e);
		} catch (NoSuchFieldException e)
		{
			throw new RuntimeException(e);
		}
	}

	//使用反射获取构造器,构造对象
	static void Constructor_Test() throws InstantiationException, IllegalAccessException, NoSuchMethodException, InvocationTargetException
	{
		//获取student类的Class对象,随程序加载一并加载到内存中
		Class stclass = student.class;

		System.out.println(student.class.getClassLoader());
		System.out.println(stclass);
		//过期的无参构造方法,根据指定的构造器创建对象
		student s1 = (student) stclass.newInstance();
		s1.age = 11;
		System.out.println(s1);

		//获取Class类构造器方法
		//1.getConstructors,返回构造器对象数组 ## getConstructor,返回单个构造器对象,以上只能拿public的构造器
		Constructor<student>[] constrcts = stclass.getConstructors();
		for (Constructor c : constrcts)
			System.out.println(c);        //无

		//2.getDeclaredConstructors,返回构造器对象数组 ## getDeclaredConstructor,返回单个构造器对象存在就能拿到
		constrcts = stclass.getDeclaredConstructors();
		for (Constructor c : constrcts)
			System.out.println(c);

		//根据参数列表的不同返回不同构造器对象
		Constructor<student> constrctor = stclass.getDeclaredConstructor(java.lang.String.class, int.class);
		System.out.println(constrctor);
		//私有方法报错,需要取消构造器的访问检查,进行暴力反射
		//student s2 = student.class.getDeclaredConstructor(java.lang.String.class, int.class).newInstance("wangwu",23);
		Constructor<student> constructor1 = student.class.getDeclaredConstructor(java.lang.String.class, int.class);
		constructor1.setAccessible(true);
		student s2 = constructor1.newInstance("wangwu", 23);
		System.out.println(s2);
	}

	//使用反射获取方法对象,并使用
	static void Method_Test() throws NoSuchMethodException, InvocationTargetException, InstantiationException, IllegalAccessException
	{
		//根据参数列表的不同返回不同构造器对象
		Constructor<student> constrctor = student.class.getDeclaredConstructor(java.lang.String.class, int.class);
		System.out.println(constrctor);
		//私有方法报错,需要取消构造器的访问检查,进行暴力反射
		//student s2 = student.class.getDeclaredConstructor(java.lang.String.class, int.class).newInstance("wangwu",23);
		Constructor<student> constructor1 = student.class.getDeclaredConstructor(java.lang.String.class, int.class);
		constructor1.setAccessible(true);
		student s2 = constructor1.newInstance("wangwu", 23);

		Method m1 = student.class.getDeclaredMethod("Print");
		m1.setAccessible(true);
		//Method类中用于触发执行的方法
		m1.invoke(s2);
	}

	//使用反射获取对象参数,并修改打印
	static void Field_Test() throws NoSuchMethodException, InvocationTargetException, InstantiationException, IllegalAccessException, NoSuchFieldException
	{
		student s1 = student.class.getDeclaredConstructor().newInstance();
		System.out.println(s1);
		Field student_name = student.class.getDeclaredField("name");
		student_name.setAccessible(true);
		student_name.set(s1, "lixixi");
		System.out.println(s1);
	}
}
